Задания по стажировки по аналитике

Вступление
...

Всем привет! Сегодня я буду проходить вместе с вами тестирование для отбора кандидатов на Стажировку от Яндекс. И, хоть мы в последнее время и изучаем Data Engineering, попасть на работу сейчас будет очень полезно. Поэтому давайте начнем, у нас всего лишь 6 часов.

Попробовать свои силы, и, возможность, стать сотрудников Яднекса можно по прикрепленной ссылке ниже:
Нажми Нажми Нажми Нажми Нажми Нажми Нажми Нажми Нажми Нажми

Приступаем к решению задач!

Очевидное

Конечно же, я нашел эти задачи в интернете, и не ручаюсь за их достоверность. Весь приведенный материал показывается исключительно в ознакомительных целях, все совпадения случайны, и нигде вообще не написано, что даже если вдруг это я реально решал эти задачи сам 6 часов 2023.09.25, то мне что-то за это будет, отстаньте.

Задача 1
...

Примечание
...

Думаю, не нужно объяснять код, потому что он максимально структурирован, хоть и не идеален. Я старался максимально разделить код на отдельные микроструктуры.

with 
t1 AS(
  SELECT *, row_number() over (partition by uuid) full_sessions
  from feed_events
  WHERE event = 'open'),
t2 AS(
  SELECT feed_events.*, t1.full_sessions
  FROM feed_events
  LEFT JOIN t1
  ON t1.uuid=feed_events.uuid
  AND t1.timestamp=feed_events.timestamp),
t3 AS(
  SELECT *
  FROM t2
  ORDER BY uuid asc,timestamp asc),
t4 AS(
  SELECT *,
  coalesce(full_sessions,
          (SELECT max(t3.full_sessions)
           from t3
           where t3.uuid=t3_1.uuid
           AND t3.timestamp<t3_1.timestamp
          
          )) sessions_num
  from t3 t3_1),
t5 as(
  SELECT DISTINCT uuid,sessions_num
  from t4
  where event='click'),
t6 AS(
  SELECT uuid, count(sessions_num) sessions
  from t5
  group by uuid),
t7 as(
  select distinct uuid, min(event) gh
  from t4
  group by uuid
  having min(event)<>'click'
),
t8 as(
  select * from t6
  UNION
  SELECT uuid, 0 sessions
  from t7)
SELECT * from t8
order by sessions desc,uuid asc
LIMIT 10

Задача 2
...

Пояснение
...

На самом деле код оказался куда более простым, чем я изначально думал.

В чем же дело?

Всё дело в том, что Яндекс неправильно написал условие задачи.
Нас просят найти наличие циклических зависимостей среди всех команд. Однако на самом деле нужно найти эти зависимости только среди тех команд, которые перенаправили Яна из его собственной команды. Ниже код с учетом этого, и он оказался правильным. Дойти до этого можно, но это не очевидно, и выясняет только путем проверочных вброс-тестов.

N=input()
b=input()
b=[int(x) for x in b.split(' ')]
ender=False
ans='NO'
i=0
while ender==False:
    if b[i]==-1:
        ender=True
    if b[i]==-2:
        ans='YES'
        ender=True
    if b[i]!=-1 and b[i]!=-2:
        t=i
        i=b[i]
        b[t]=-2
    # print(f"{b}")
    

print(ans)

Задача 3
...

Пояснения
...

Данная задача непомерно сложная по сравнению с другими, так как требует очень долгого анализа и кропотливой работы, потому что ограничение по времени и памяти слишком сильное.

Интересный факт

Данная задача использовалась на олимпиаде Росатом 2022-2023 годов. Найти ее можно в данном файле, а именно задача №2. Решение там неполное, и очень сложное к пониманию (Это же не Python 🙂)

Задача 4
...

Пояснение
...

Очень интересная задача. Я, наверное, только час думал над тем, какой самый лучший метод нужно использовать для наибольшей вероятности выигрыша. И только спустя час, до меня дошло:

  • Стратегии нет! От количества пропущенных карт, среднестатистическое отношение простых чисел к общему набору будет оставаться всегда прежним! А это в свою очередь значит, что Аркадий может останавливать игру в абсолютно любой момент, и в абсолютно любой момент его общая вероятность победы будет оставаться на прежнем уровне, а именно (Кол-во Простых Чисел) / (Всего чисел). Всё, что нам остается сделать (иначе не пройдем по ограничениям), это использовать один из наибыстрейших методов нахождения кол-ва простых чисел, это гуглится, есть быстрые алгоритмы. Ниже один из них.
n=int(input())
def primes(n):
    """ Returns  a list of primes < n """
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return len([2] + [i for i in range(3,n,2) if sieve[i]])

a=primes(n)
t=round(float(a/n),2)
print(f'{t:.2f}')

Задача 5
...

Пояснение
...

Моя самая любимая задача - задача на Теорию Вероятностей! Однако тут, в отличии от других задач, много кодить не получится, нужно считать...
Вот мои вычисления, был найден мною метод упрощения и сокращения почти всех элементов произведения обратной вероятности, что позволяет считать абсолютно для любого числа вероятность (проверял, 100000000 считается за 0.3 секунды, в ограничения заходим).

Что такое Fraction?

Это модуль для оптимального сокращения дробей до неделимых частей. И не надо говорить что нужно самому это делать, я кучу времени про💩л на то чтобы придумать хоть что-то

from fractions import Fraction
n=int(input())
a=1
b=1
if n<=100:

    for i in range(1,n+1):
        if n==1:
            a*=i*(i+4)*(i+5)
            b*=(i+1)*(i+2)*(i+6)
        else:
            if (i==1):
                a*=i*(i+4)*(i+5)
                b*=(i+2)
            elif i==n:
                a*=(i+4)
                b*=(i+1)*(i+2)*(i+6)
            else:
                a*=(i+4)
                b*=(i+2)
else:
    a=(n+4)*(n+3)*(n+2) 
    b=2*(n+1)*(n+2)*(n+6)
a=b-a
# print(a,b)
q=Fraction(a,b)
print(q.numerator,q.denominator)

# a*=i*(i+4)*(i+5)
# b*=(i+1)*(i+2)*(i+6)

Задача 6
...


Ну, эту задачу для грузчиков даже мне лень решать. Предлагаю кому-нибудь взять ее в качестве самостоятельного изучения, если кто-нибудь когда-нибудь отправит мне решение этой задачи, я лично вручу ему 100 рублей. В каком бы месте мира он не находился (ну, только договориться надо о встрече).


ИТОГО
...

Как видно, я решил всего лишь 4 из 6 задач, однако я считаю это очень и очень хорошим результатом. Ну и конечно же, SQLite3 сосёт бибу перед PostgreSQL)))))